/**
 * @file gpio_lib.c
 * @brief 通用GPIO操作库实现
 * 
 * 提供GPIO操作的通用函数实现，以提高代码复用性和移植性。
 * 
 * @author 伞控无人机项目组
 * @date 2023
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include "gpio_lib.h"
#include <time.h>
#include <sys/syscall.h>

// 模块名称定义
#define GPIO_MODULE_NAME LOG_MODULE_GPIO

// 最大支持的GPIO句柄数量
#define MAX_GPIO_HANDLES 32

// GPIO路径定义
#define GPIO_EXPORT      "/sys/class/gpio/export"
#define GPIO_UNEXPORT    "/sys/class/gpio/unexport"
#define GPIO_BASE_PATH   "/sys/class/gpio/gpio"
#define MAX_RETRY_COUNT  5         // 最大重试次数
#define RETRY_DELAY_MS   500       // 重试延迟（毫秒）

// GPIO配置文件路径
#define GPIO_CONFIG_FILE "gpio_config.dat"

// 全局变量：已注册的GPIO句柄列表，用于自动清理
static gpio_handle_t *g_gpio_handles[MAX_GPIO_HANDLES] = {NULL};
static int g_gpio_handle_count = 0;

// 已占用的GPIO编号列表，防止多线程访问同一个GPIO资源
#define MAX_GPIO_PINS 256  // 最大支持的GPIO编号
static int g_gpio_pin_used[MAX_GPIO_PINS] = {0};  // 0表示未使用，1表示已使用
static pthread_mutex_t g_gpio_lib_mutex = PTHREAD_MUTEX_INITIALIZER;  // 保护全局数据的互斥锁

// 库初始化标志
static int g_gpio_lib_initialized = 0;

// 信号处理相关的全局变量（异步安全）
static volatile sig_atomic_t g_cleanup_requested = 0;
static volatile sig_atomic_t g_signal_cleanup_in_progress = 0;

/**
 * @brief 异步安全的GPIO清理函数
 * 
 * 这个函数只使用异步安全的系统调用，可以在信号处理函数中安全调用
 * 不使用日志系统、互斥锁或其他非异步安全的函数
 */
static void cleanup_gpios_async_safe(void)
{
    // 防止重复调用
    if (g_signal_cleanup_in_progress) {
        return;
    }
    
    g_signal_cleanup_in_progress = 1;
    
    // 简单的错误信息输出（异步安全）
    const char start_msg[] = "GPIO: 开始异步安全清理...\n";
    ssize_t result = write(STDERR_FILENO, start_msg, sizeof(start_msg) - 1);
    (void)result;  // 避免未使用返回值警告
    
    // 直接访问全局数据（不使用互斥锁，因为在信号处理中）
    // 注意：这里存在竞态条件的风险，但在异常退出时可以接受
    for (int i = 0; i < g_gpio_handle_count && i < MAX_GPIO_HANDLES; i++) {
        gpio_handle_t *handle = g_gpio_handles[i];
        if (handle && handle->is_initialized) {
            // 构造GPIO编号字符串
            char gpio_str[16];
            int gpio_num = handle->gpio_num;
            
            // 手动转换数字为字符串（避免使用snprintf）
            int len = 0;
            int temp = gpio_num;
            if (temp == 0) {
                gpio_str[len++] = '0';
            } else {
                char temp_str[16];
                int temp_len = 0;
                while (temp > 0) {
                    temp_str[temp_len++] = '0' + (temp % 10);
                    temp /= 10;
                }
                // 反转字符串
                for (int j = temp_len - 1; j >= 0; j--) {
                    gpio_str[len++] = temp_str[j];
                }
            }
            gpio_str[len] = '\0';
            
            // 尝试取消导出GPIO（使用简单的文件操作）
            int fd = open(GPIO_UNEXPORT, O_WRONLY);
            if (fd >= 0) {
                write(fd, gpio_str, len);
                close(fd);
            }
            
            // 重置句柄状态
            handle->is_initialized = 0;
            
            // 释放GPIO占用标记（直接访问，不使用互斥锁）
            if (gpio_num >= 0 && gpio_num < MAX_GPIO_PINS) {
                g_gpio_pin_used[gpio_num] = 0;
            }
        }
    }
    
    // 重置全局计数器
    g_gpio_handle_count = 0;
    
    const char end_msg[] = "GPIO: 异步安全清理完成\n";
    result = write(STDERR_FILENO, end_msg, sizeof(end_msg) - 1);
    (void)result;
}

/**
 * @brief 使用重试机制写入文件
 * 
 * @param path 文件路径
 * @param value 要写入的值
 * @param len 值的长度
 * @return int 成功返回0，失败返回-1
 */
static int write_with_retry(const char *path, const char *value, size_t len)
{
    int fd;
    int retry_count = 0;
    int result = -1;
    
    while (retry_count < MAX_RETRY_COUNT) {
        fd = open(path, O_WRONLY);
        if (fd < 0) {
            LOG_DEBUG(LOG_TO_CONSOLE_ONLY, GPIO_MODULE_NAME, "打开文件 %s 失败: %s，尝试重试 (%d/%d)", 
                    path, strerror(errno), retry_count + 1, MAX_RETRY_COUNT);
            retry_count++;
            usleep(RETRY_DELAY_MS * 1000);
            continue;
        }
        
        if (write(fd, value, len) < 0) {
            // 如果已经导出，则忽略EBUSY错误
            if (errno == EBUSY && strstr(path, "export") != NULL) {
                result = 0;  // 视为成功
            } else {
                LOG_DEBUG(LOG_TO_CONSOLE_ONLY, GPIO_MODULE_NAME, "写入文件 %s 失败: %s，尝试重试 (%d/%d)", 
                        path, strerror(errno), retry_count + 1, MAX_RETRY_COUNT);
                result = -1;
            }
        } else {
            result = 0;  // 写入成功
        }
        
        close(fd);
        
        if (result == 0) {
            break;  // 操作成功，跳出循环
        }
        
        retry_count++;
        usleep(RETRY_DELAY_MS * 1000);
    }
    
    return result;
}

/**
 * @brief 使用重试机制读取文件
 * 
 * @param path 文件路径
 * @param value 保存读取结果的缓冲区
 * @param len 要读取的字节数
 * @return int 成功返回读取的字节数，失败返回-1
 */
static int read_with_retry(const char *path, char *value, size_t len)
{
    int fd;
    int retry_count = 0;
    int result = -1;
    
    while (retry_count < MAX_RETRY_COUNT) {
        fd = open(path, O_RDONLY);
        if (fd < 0) {
            LOG_DEBUG(LOG_TO_CONSOLE_ONLY, GPIO_MODULE_NAME, "打开文件 %s 失败: %s，尝试重试 (%d/%d)", 
                    path, strerror(errno), retry_count + 1, MAX_RETRY_COUNT);
            retry_count++;
            usleep(RETRY_DELAY_MS * 1000);
            continue;
        }
        
        result = read(fd, value, len);
        if (result < 0) {
            LOG_DEBUG(LOG_TO_CONSOLE_ONLY, GPIO_MODULE_NAME, "读取文件 %s 失败: %s，尝试重试 (%d/%d)", 
                    path, strerror(errno), retry_count + 1, MAX_RETRY_COUNT);
        }
        
        close(fd);
        
        if (result > 0) {
            break;  // 读取成功，跳出循环
        }
        
        retry_count++;
        usleep(RETRY_DELAY_MS * 1000);
    }
    
    return result;
}

/**
 * @brief 将GPIO句柄注册到全局列表，用于自动清理
 * 
 * @param handle GPIO句柄指针
 */
static void register_gpio_handle(gpio_handle_t *handle)
{
    if (!handle || g_gpio_handle_count >= MAX_GPIO_HANDLES) {
        return;
    }
    
    pthread_mutex_lock(&g_gpio_lib_mutex);
    
    // 检查是否已注册
    for (int i = 0; i < g_gpio_handle_count; i++) {
        if (g_gpio_handles[i] == handle) {
            pthread_mutex_unlock(&g_gpio_lib_mutex);
            return;  // 已注册
        }
    }
    
    // 注册到列表
    g_gpio_handles[g_gpio_handle_count++] = handle;
    
    pthread_mutex_unlock(&g_gpio_lib_mutex);
}

/**
 * @brief 从全局列表中取消注册GPIO句柄
 * 
 * @param handle GPIO句柄指针
 */
static void unregister_gpio_handle(gpio_handle_t *handle)
{
    if (!handle) {
        return;
    }
    
    pthread_mutex_lock(&g_gpio_lib_mutex);
    
    for (int i = 0; i < g_gpio_handle_count; i++) {
        if (g_gpio_handles[i] == handle) {
            // 移除句柄
            g_gpio_handles[i] = NULL;
            
            // 压缩列表
            for (int j = i; j < g_gpio_handle_count - 1; j++) {
                g_gpio_handles[j] = g_gpio_handles[j + 1];
            }
            
            g_gpio_handle_count--;
            break;
        }
    }
    
    pthread_mutex_unlock(&g_gpio_lib_mutex);
}

/**
 * @brief 检查某个GPIO编号是否已被使用
 * 
 * @param gpio_num GPIO编号
 * @return int 1表示已使用，0表示未使用
 */
static int is_gpio_used(int gpio_num)
{
    if (gpio_num < 0 || gpio_num >= MAX_GPIO_PINS) {
        return 0;
    }
    
    return g_gpio_pin_used[gpio_num];
}

/**
 * @brief 标记GPIO编号为已使用
 * 
 * @param gpio_num GPIO编号
 * @param used 1表示使用，0表示释放
 */
static void mark_gpio_used(int gpio_num, int used)
{
    if (gpio_num < 0 || gpio_num >= MAX_GPIO_PINS) {
        return;
    }
    
    g_gpio_pin_used[gpio_num] = used;
}

/**
 * @brief 将GPIO引脚名转换为GPIO编号
 * 
 * @param gpio_pin GPIO引脚名，格式为"X_YZ_d"，例如"4_A2_d"
 * @return int 成功返回GPIO编号，失败返回-1
 */
int gpio_name_to_number(const char *gpio_pin)
{
    // 解析GPIO引脚名，格式为 "X_YZ_d"
    // 其中X是GPIO组，Y是GPIO组内的子组，Z是子组内的引脚编号
    int group, pin;
    char subgroup_char;
    
    if (sscanf(gpio_pin, "%d_%c%d_d", &group, &subgroup_char, &pin) != 3) {
        LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "无效的GPIO引脚格式: %s", gpio_pin);
        return -1;
    }
    
    // 根据RK3568的GPIO编号规则计算GPIO编号
    // RK3568的GPIO编号规则：GPIO4_A3 = 128 + 0*8 + 3 = 131
    // 基础偏移：GPIO0=0, GPIO1=32, GPIO2=64, GPIO3=96, GPIO4=128
    int base_offset;
    switch (group) {
        case 0: base_offset = 0; break;
        case 1: base_offset = 32; break;
        case 2: base_offset = 64; break;
        case 3: base_offset = 96; break;
        case 4: base_offset = 128; break;  // RK3568：GPIO4从128开始
        default: 
            LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "不支持的GPIO组: %d", group);
            return -1;
    }
    
    int gpio_num = base_offset + (subgroup_char - 'A') * 8 + pin;
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, GPIO_MODULE_NAME, "GPIO编号计算: %s -> group=%d, subgroup=%c, pin=%d -> %d+%d+%d=%d", 
              gpio_pin, group, subgroup_char, pin, base_offset, (subgroup_char - 'A') * 8, pin, gpio_num);
    
    return gpio_num;
}

/**
 * @brief 保存GPIO配置到文件
 * 
 * 将当前所有已初始化的GPIO配置保存到文件中
 * 
 * @return int 成功返回0，失败返回负数
 */
int gpio_save_config(void)
{
    FILE *fp;
    int ret = 0;
    
    if (!g_gpio_lib_initialized) {
        LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "库尚未初始化，无法保存配置");
        return -1;
    }
    
    pthread_mutex_lock(&g_gpio_lib_mutex);
    
    fp = fopen(GPIO_CONFIG_FILE, "wb");
    if (!fp) {
        LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "无法创建配置文件: %s", strerror(errno));
        pthread_mutex_unlock(&g_gpio_lib_mutex);
        return -1;
    }
    
    // 写入GPIO句柄数量
    fwrite(&g_gpio_handle_count, sizeof(int), 1, fp);
    
    // 写入每个GPIO句柄的配置
    for (int i = 0; i < g_gpio_handle_count; i++) {
        if (g_gpio_handles[i] && g_gpio_handles[i]->is_initialized) {
            // 写入GPIO编号
            fwrite(&g_gpio_handles[i]->gpio_num, sizeof(int), 1, fp);
            
            // 写入GPIO名称
            size_t name_len = strlen(g_gpio_handles[i]->gpio_name);
            fwrite(&name_len, sizeof(size_t), 1, fp);
            fwrite(g_gpio_handles[i]->gpio_name, 1, name_len, fp);
            
            // 读取当前GPIO方向
            char direction_path[128];
            char direction_value[10] = {0};
            snprintf(direction_path, sizeof(direction_path), "%s%d/direction", GPIO_BASE_PATH, g_gpio_handles[i]->gpio_num);
            int dir_read = read_with_retry(direction_path, direction_value, sizeof(direction_value) - 1);
            
            // 写入方向信息
            int is_input = (dir_read > 0 && strncmp(direction_value, "in", 2) == 0) ? 1 : 0;
            fwrite(&is_input, sizeof(int), 1, fp);
            
            // 如果是输入模式，读取边沿触发信息
            if (is_input) {
                char edge_path[128];
                char edge_value[10] = {0};
                snprintf(edge_path, sizeof(edge_path), "%s%d/edge", GPIO_BASE_PATH, g_gpio_handles[i]->gpio_num);
                int edge_read = read_with_retry(edge_path, edge_value, sizeof(edge_value) - 1);
                
                // 确定边沿触发方式
                int edge_mode = GPIO_EDGE_NONE;
                if (edge_read > 0) {
                    if (strncmp(edge_value, "rising", 6) == 0) {
                        edge_mode = GPIO_EDGE_RISING;
                    } else if (strncmp(edge_value, "falling", 7) == 0) {
                        edge_mode = GPIO_EDGE_FALLING;
                    } else if (strncmp(edge_value, "both", 4) == 0) {
                        edge_mode = GPIO_EDGE_BOTH;
                    }
                }
                
                // 写入边沿触发方式
                fwrite(&edge_mode, sizeof(int), 1, fp);
            } else {
                // 如果是输出模式，读取当前值
                char value_path[128];
                char value[2] = {0};
                snprintf(value_path, sizeof(value_path), "%s%d/value", GPIO_BASE_PATH, g_gpio_handles[i]->gpio_num);
                int val_read = read_with_retry(value_path, value, 1);
                
                // 写入当前值
                int gpio_value = (val_read > 0 && value[0] == '1') ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW;
                fwrite(&gpio_value, sizeof(int), 1, fp);
            }
        }
    }
    
    fclose(fp);
    
    LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO配置已保存到 %s 文件", GPIO_CONFIG_FILE);
    
    pthread_mutex_unlock(&g_gpio_lib_mutex);
    return ret;
}

/**
 * @brief 从文件加载GPIO配置
 * 
 * 从配置文件中加载并初始化所有GPIO
 * 
 * @return int 成功返回0，失败返回负数
 */
int gpio_load_config(void)
{
    FILE *fp;
    int ret = 0;
    int loaded_count = 0;
    
    if (!g_gpio_lib_initialized) {
        LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "库尚未初始化，无法加载配置");
        return -1;
    }
    
    fp = fopen(GPIO_CONFIG_FILE, "rb");
    if (!fp) {
        // 没有配置文件不算错误
        return 0;
    }
    
    pthread_mutex_lock(&g_gpio_lib_mutex);
    
    // 读取GPIO句柄数量
    int handle_count;
    if (fread(&handle_count, sizeof(int), 1, fp) != 1) {
        LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "配置文件格式错误");
        fclose(fp);
        pthread_mutex_unlock(&g_gpio_lib_mutex);
        return -1;
    }
    
    // 读取每个GPIO句柄的配置
    for (int i = 0; i < handle_count; i++) {
        int gpio_num;
        size_t name_len;
        char gpio_name[64];
        int is_input;
        
        // 读取GPIO编号
        if (fread(&gpio_num, sizeof(int), 1, fp) != 1) {
            break;
        }
        
        // 读取GPIO名称
        if (fread(&name_len, sizeof(size_t), 1, fp) != 1 || name_len >= sizeof(gpio_name)) {
            break;
        }
        if (fread(gpio_name, 1, name_len, fp) != name_len) {
            break;
        }
        gpio_name[name_len] = '\0';
        
        // 读取方向信息
        if (fread(&is_input, sizeof(int), 1, fp) != 1) {
            break;
        }
        
        // 检查GPIO是否已被使用
        if (!is_gpio_used(gpio_num)) {
            // 导出GPIO
            char gpio_str[16];
            snprintf(gpio_str, sizeof(gpio_str), "%d", gpio_num);
            write_with_retry(GPIO_EXPORT, gpio_str, strlen(gpio_str));
            usleep(100000);  // 100ms
            
            // 设置方向
            char direction_path[128];
            snprintf(direction_path, sizeof(direction_path), "%s%d/direction", GPIO_BASE_PATH, gpio_num);
            write_with_retry(direction_path, is_input ? "in" : "out", is_input ? 2 : 3);
            
            if (is_input) {
                // 读取边沿触发方式
                int edge_mode;
                if (fread(&edge_mode, sizeof(int), 1, fp) == 1) {
                    char edge_path[128];
                    snprintf(edge_path, sizeof(edge_path), "%s%d/edge", GPIO_BASE_PATH, gpio_num);
                    
                    const char *edge_str = "none";
                    switch (edge_mode) {
                        case GPIO_EDGE_RISING: edge_str = "rising"; break;
                        case GPIO_EDGE_FALLING: edge_str = "falling"; break;
                        case GPIO_EDGE_BOTH: edge_str = "both"; break;
                        default: edge_str = "none"; break;
                    }
                    
                    write_with_retry(edge_path, edge_str, strlen(edge_str));
                    
                    // 标记GPIO为已使用
                    mark_gpio_used(gpio_num, 1);
                    loaded_count++;
                    
                    LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "已从配置文件恢复GPIO%d(%s)为输入模式，边沿触发=%s", 
                           gpio_num, gpio_name, edge_str);
                }
            } else {
                // 读取输出值
                int gpio_value;
                if (fread(&gpio_value, sizeof(int), 1, fp) == 1) {
                    // 设置输出值
                    char value_path[128];
                    snprintf(value_path, sizeof(value_path), "%s%d/value", GPIO_BASE_PATH, gpio_num);
                    write_with_retry(value_path, gpio_value == GPIO_VALUE_HIGH ? "1" : "0", 1);
                    
                    // 标记GPIO为已使用
                    mark_gpio_used(gpio_num, 1);
                    loaded_count++;
                    
                    LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "已从配置文件恢复GPIO%d(%s)为输出模式，值=%d", 
                           gpio_num, gpio_name, gpio_value);
                }
            }
        }
    }
    
    fclose(fp);
    
    if (loaded_count > 0) {
        LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO配置加载完成，成功恢复%d个GPIO", loaded_count);
    }
    
    pthread_mutex_unlock(&g_gpio_lib_mutex);
    return ret;
}

/**
 * @brief 初始化GPIO
 * 
 * @param handle GPIO句柄指针，用于保存初始化结果
 * @param gpio_pin GPIO引脚名，格式为"X_YZ_d"，例如"4_A2_d"
 * @param direction GPIO方向，输入或输出
 * @param edge 边沿触发方式（仅对输入有效）
 * @return int 成功返回0，失败返回负数
 */
int gpio_init(gpio_handle_t *handle, const char *gpio_pin, gpio_direction_t direction, gpio_edge_t edge)
{
    if (!handle || !gpio_pin) {
        return -1;
    }
    
    // 确保库已经初始化
    if (!g_gpio_lib_initialized) {
        LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "库尚未初始化，应先调用gpio_register_cleanup_handlers()");
        return -1;
    }
    
    // 转换GPIO编号
    int gpio_num = gpio_name_to_number(gpio_pin);
    if (gpio_num < 0) {
        return -1;
    }
    
    // 检查GPIO文件是否已经存在
    char gpio_path[128];
    snprintf(gpio_path, sizeof(gpio_path), "%s%d", GPIO_BASE_PATH, gpio_num);
    
    int gpio_already_exported = (access(gpio_path, F_OK) == 0);
    
    pthread_mutex_lock(&g_gpio_lib_mutex);
    
    // 如果GPIO文件不存在，检查是否被其他线程使用
    if (!gpio_already_exported && is_gpio_used(gpio_num)) {
        LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO %d(%s) 已被其他线程使用，无法初始化", gpio_num, gpio_pin);
        pthread_mutex_unlock(&g_gpio_lib_mutex);
        return -2;  // 特殊错误码，表示资源冲突
    }
    
    // 标记为已使用
    mark_gpio_used(gpio_num, 1);
    
    pthread_mutex_unlock(&g_gpio_lib_mutex);
    
    // 初始化句柄
    handle->gpio_num = gpio_num;
    strncpy(handle->gpio_name, gpio_pin, sizeof(handle->gpio_name) - 1);
    handle->gpio_name[sizeof(handle->gpio_name) - 1] = '\0';
    handle->is_initialized = 0;
    
    // 如果GPIO文件已存在，直接使用；否则导出GPIO
    if (gpio_already_exported) {
        LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO%d(%s)文件已存在，直接使用", gpio_num, gpio_pin);
    } else {
        // 导出GPIO
        char gpio_str[16];
        snprintf(gpio_str, sizeof(gpio_str), "%d", gpio_num);
        if (write_with_retry(GPIO_EXPORT, gpio_str, strlen(gpio_str)) < 0) {
            LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "导出GPIO %d 失败", gpio_num);
            pthread_mutex_lock(&g_gpio_lib_mutex);
            mark_gpio_used(gpio_num, 0);  // 释放占用标记
            pthread_mutex_unlock(&g_gpio_lib_mutex);
            return -1;
        }
        
        // 给系统一点时间来创建GPIO文件
        usleep(100000);  // 100ms
        LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO%d(%s)导出成功", gpio_num, gpio_pin);
    }
    
    // 设置GPIO方向
    char direction_path[128];
    snprintf(direction_path, sizeof(direction_path), "%s%d/direction", GPIO_BASE_PATH, gpio_num);
    
    const char *dir_str = (direction == GPIO_DIR_INPUT) ? "in" : "out";
    if (write_with_retry(direction_path, dir_str, strlen(dir_str)) < 0) {
        LOG_ERROR(LOG_TO_FILE, GPIO_MODULE_NAME, "设置GPIO %d 方向失败", gpio_num);
        pthread_mutex_lock(&g_gpio_lib_mutex);
        mark_gpio_used(gpio_num, 0);  // 释放占用标记
        pthread_mutex_unlock(&g_gpio_lib_mutex);
        return -1;
    }
    
    // 如果是输入模式且设置了边沿触发，则配置边沿触发方式
    if (direction == GPIO_DIR_INPUT && edge != GPIO_EDGE_NONE) {
        char edge_path[128];
        snprintf(edge_path, sizeof(edge_path), "%s%d/edge", GPIO_BASE_PATH, gpio_num);
        
        const char *edge_str;
        switch (edge) {
            case GPIO_EDGE_RISING:
                edge_str = "rising";
                break;
            case GPIO_EDGE_FALLING:
                edge_str = "falling";
                break;
            case GPIO_EDGE_BOTH:
                edge_str = "both";
                break;
            default:
                edge_str = "none";
                break;
        }
        
        if (write_with_retry(edge_path, edge_str, strlen(edge_str)) < 0) {
            LOG_WARN(LOG_TO_FILE, GPIO_MODULE_NAME, "设置GPIO %d 边沿触发方式失败", gpio_num);
            // 不返回错误，因为这不是致命错误
        }
    }
    
    // 标记为已初始化
    handle->is_initialized = 1;
    
    // 注册句柄，用于自动清理
    register_gpio_handle(handle);
    
    LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO%d(%s)初始化成功，设置为%s模式", 
           gpio_num, gpio_pin, (direction == GPIO_DIR_INPUT) ? "输入" : "输出");
    
    return 0;
}

/**
 * @brief 读取GPIO状态
 * 
 * @param handle 已初始化的GPIO句柄
 * @return int 成功返回GPIO状态(0或1)，失败返回负数
 */
int gpio_read(const gpio_handle_t *handle)
{
    if (!handle || !handle->is_initialized) {
        return -1;
    }
    
    // 读取GPIO值
    char value_path[128];
    snprintf(value_path, sizeof(value_path), "%s%d/value", GPIO_BASE_PATH, handle->gpio_num);
    
    char value;
    if (read_with_retry(value_path, &value, 1) < 1) {
        return -1;
    }
    
    return (value == '1') ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW;
}

/**
 * @brief 设置GPIO状态（仅对输出模式有效）
 * 
 * @param handle 已初始化的GPIO句柄
 * @param value 要设置的值，0或1
 * @return int 成功返回0，失败返回负数
 */
int gpio_write(const gpio_handle_t *handle, gpio_value_t value)
{
    if (!handle || !handle->is_initialized) {
        return -1;
    }
    
    // 写入GPIO值
    char value_path[128];
    snprintf(value_path, sizeof(value_path), "%s%d/value", GPIO_BASE_PATH, handle->gpio_num);
    
    const char *val_str = (value == GPIO_VALUE_HIGH) ? "1" : "0";
    if (write_with_retry(value_path, val_str, 1) < 0) {
        return -1;
    }
    
    return 0;
}

/**
 * @brief 切换GPIO输出状态（仅对输出模式有效）
 * 
 * @param handle 已初始化的GPIO句柄
 * @return int 成功返回0，失败返回负数
 */
int gpio_toggle(const gpio_handle_t *handle)
{
    if (!handle || !handle->is_initialized) {
        return -1;
    }
    
    // 先读取当前值
    int current_value = gpio_read(handle);
    if (current_value < 0) {
        return -1;
    }
    
    // 切换值
    gpio_value_t new_value = (current_value == GPIO_VALUE_HIGH) ? GPIO_VALUE_LOW : GPIO_VALUE_HIGH;
    
    return gpio_write(handle, new_value);
}

/**
 * @brief 释放GPIO资源
 * 
 * @param handle 要释放的GPIO句柄
 */
void gpio_cleanup(gpio_handle_t *handle)
{
    if (!handle || !handle->is_initialized) {
        return;
    }
    
    // 取消导出GPIO
    char gpio_str[16];
    snprintf(gpio_str, sizeof(gpio_str), "%d", handle->gpio_num);
    
    if (write_with_retry(GPIO_UNEXPORT, gpio_str, strlen(gpio_str)) < 0) {
        LOG_WARN(LOG_TO_FILE, GPIO_MODULE_NAME, "取消导出GPIO%d失败", handle->gpio_num);
    } else {
        LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO%d(%s)资源已清理", handle->gpio_num, handle->gpio_name);
    }
    
    // 取消注册句柄
    unregister_gpio_handle(handle);
    
    // 释放GPIO占用标记
    pthread_mutex_lock(&g_gpio_lib_mutex);
    mark_gpio_used(handle->gpio_num, 0);
    pthread_mutex_unlock(&g_gpio_lib_mutex);
    
    // 重置句柄
    handle->is_initialized = 0;
}

/**
 * @brief 清理所有已注册的GPIO资源（正常清理版本）
 * 
 * 这个版本使用完整的错误处理和日志记录，适用于正常程序退出
 */
static void cleanup_all_gpios(void)
{
    // 防止重复调用的静态标志
    static volatile int cleanup_in_progress = 0;
    static volatile int cleanup_completed = 0;
    
    // 原子性检查和设置标志（简单的防重复机制）
    if (cleanup_completed) {
        LOG_DEBUG(LOG_TO_CONSOLE_ONLY, GPIO_MODULE_NAME, "GPIO资源已经清理过，跳过重复清理");
        return;
    }
    
    if (cleanup_in_progress) {
        LOG_WARN(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO清理正在进行中，避免重复调用");
        return;
    }
    
    cleanup_in_progress = 1;
    
    LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "清理所有GPIO资源...");
    
    // 首先保存当前配置，便于下次恢复
    gpio_save_config();
    
    pthread_mutex_lock(&g_gpio_lib_mutex);
    
    for (int i = 0; i < g_gpio_handle_count; i++) {
        if (g_gpio_handles[i]) {
            gpio_handle_t *handle = g_gpio_handles[i];
            
            // 取消导出GPIO
            char gpio_str[16];
            snprintf(gpio_str, sizeof(gpio_str), "%d", handle->gpio_num);
            write_with_retry(GPIO_UNEXPORT, gpio_str, strlen(gpio_str));
            
            // 重置句柄
            handle->is_initialized = 0;
            
            // 释放GPIO占用标记
            mark_gpio_used(handle->gpio_num, 0);
            
            LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO%d(%s)资源已清理", handle->gpio_num, handle->gpio_name);
        }
    }
    
    g_gpio_handle_count = 0;
    
    pthread_mutex_unlock(&g_gpio_lib_mutex);
    
    cleanup_completed = 1;
    cleanup_in_progress = 0;
    
    LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO资源清理完成");
}

/**
 * @brief 异步安全的信号处理函数
 * 
 * 只使用异步安全的系统调用，避免死锁和未定义行为
 * 
 * @param signum 信号编号
 */
static void signal_handler(int signum)
{
    // 避免未使用参数警告（保留 signum 使用）
    // 防止重复处理
    if (g_cleanup_requested) {
        return;
    }

    g_cleanup_requested = 1;

    // 异步安全输出：捕获到的信号、PID、时间戳（epoch秒）
    {
        const char prefix1[] = "GPIO: 捕获异常信号 signum=";
        const char mid1[] = " pid=";
        const char mid2[] = " epoch=";
        const char newline[] = "\n";

        // 将整数转换为字符串（避免使用非异步安全的printf/snprintf）
        char sig_str[16];
        size_t sig_len = 0;
        {
            int value = signum;
            if (value == 0) {
                sig_str[sig_len++] = '0';
            } else {
                char tmp[16];
                int t = 0;
                while (value > 0 && t < (int)sizeof(tmp)) { tmp[t++] = (char)('0' + (value % 10)); value /= 10; }
                for (int i = t - 1; i >= 0; --i) sig_str[sig_len++] = tmp[i];
            }
            sig_str[sig_len] = '\0';
        }

        char pid_str[32];
        size_t pid_len = 0;
        {
            pid_t pid = getpid();
            long value = (long)pid;
            if (value == 0) { pid_str[pid_len++] = '0'; }
            else {
                char tmp[32]; int t = 0;
                while (value > 0 && t < (int)sizeof(tmp)) { tmp[t++] = (char)('0' + (value % 10)); value /= 10; }
                for (int i = t - 1; i >= 0; --i) pid_str[pid_len++] = tmp[i];
            }
            pid_str[pid_len] = '\0';
        }

        char epoch_str[32];
        size_t epoch_len = 0;
        {
            struct timespec ts;
            long sec = 0;
            // 使用直接系统调用以尽量减少依赖；失败则保持0
            if (syscall(SYS_clock_gettime, CLOCK_REALTIME, &ts) == 0) {
                sec = ts.tv_sec;
            }
            long value = sec;
            if (value == 0) { epoch_str[epoch_len++] = '0'; }
            else {
                char tmp[32]; int t = 0;
                while (value > 0 && t < (int)sizeof(tmp)) { tmp[t++] = (char)('0' + (value % 10)); value /= 10; }
                for (int i = t - 1; i >= 0; --i) epoch_str[epoch_len++] = tmp[i];
            }
            epoch_str[epoch_len] = '\0';
        }

        // 逐段输出，保持异步安全
        (void)write(STDERR_FILENO, prefix1, sizeof(prefix1) - 1);
        (void)write(STDERR_FILENO, sig_str, sig_len);
        (void)write(STDERR_FILENO, mid1, sizeof(mid1) - 1);
        (void)write(STDERR_FILENO, pid_str, pid_len);
        (void)write(STDERR_FILENO, mid2, sizeof(mid2) - 1);
        (void)write(STDERR_FILENO, epoch_str, epoch_len);
        (void)write(STDERR_FILENO, newline, sizeof(newline) - 1);
    }

    // 执行异步安全的清理
    cleanup_gpios_async_safe();

    // 使用_exit而不是exit，避免触发atexit处理函数；
    // 退出码使用 128+signum，便于外部守护脚本识别异常并重启
    _exit(128 + signum);
}

/**
 * @brief GPIO库初始化函数
 * 
 * 初始化GPIO库，设置全局资源
 * 
 * @return int 成功返回0，失败返回负数
 */
static int gpio_lib_init(void)
{
    // 初始化GPIO占用标记
    memset(g_gpio_pin_used, 0, sizeof(g_gpio_pin_used));
    
    // 初始化GPIO句柄列表
    for (int i = 0; i < MAX_GPIO_HANDLES; i++) {
        g_gpio_handles[i] = NULL;
    }
    
    g_gpio_handle_count = 0;
    g_gpio_lib_initialized = 1;
    
    // 初始化信号处理相关变量
    g_cleanup_requested = 0;
    g_signal_cleanup_in_progress = 0;
    
    LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "GPIO库初始化成功");
    
    return 0;
}

/**
 * @brief 注册GPIO清理函数
 * 
 * 注册信号处理函数，确保在程序异常退出时释放GPIO资源
 */
void gpio_register_cleanup_handlers(void)
{
    // 初始化库
    if (!g_gpio_lib_initialized) {
        gpio_lib_init();
    }

    // 只注册异常信号处理函数，避免与main.c的信号处理函数冲突
    // 使用异步安全的信号处理函数
    signal(SIGSEGV, signal_handler);
    signal(SIGABRT, signal_handler);
    // 扩展更多致命异常信号
    signal(SIGFPE,  signal_handler);
    signal(SIGBUS,  signal_handler);
    signal(SIGILL,  signal_handler);
#ifdef SIGTRAP
    signal(SIGTRAP, signal_handler);
#endif
    // 避免因SIGPIPE导致程序退出（如写入已关闭管道/套接字）
    signal(SIGPIPE, SIG_IGN);

    // 注册退出处理函数（作为备用清理机制）
    // 注意：atexit注册的函数在正常退出时调用，可以使用完整的清理函数
    atexit(cleanup_all_gpios);

    // 尝试从配置文件加载之前的GPIO配置
    if (access(GPIO_CONFIG_FILE, F_OK) == 0) {
        LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "发现GPIO配置文件，尝试加载...");
        gpio_load_config();
    }

    LOG_INFO(LOG_TO_FILE, GPIO_MODULE_NAME, "已注册GPIO异常清理处理函数（包含SIGSEGV/SIGABRT/SIGFPE/SIGBUS/SIGILL等，且忽略SIGPIPE）");
}

/**
 * @brief 手动清理所有GPIO资源（公共接口）
 * 
 * 提供给外部调用的GPIO清理接口，可以在程序正常退出时手动调用
 */
void gpio_cleanup_all(void)
{
    cleanup_all_gpios();
} 